#!/usr/bin/python
# -*- coding: UTF-8 -*-
""""
@reference
    http://www.liaoxuefeng.com/wiki/001374738125095c955c1e6d8bb493182103fac9270762a000/001386832745198026a685614e7462fb57dbf733cc9f3ad000
    http://www.cnblogs.com/lonelycatcher/archive/2012/02/09/2343463.html
    [邮件发送模型及其Python应用实例](http://www.cnblogs.com/benxintuzi/p/5514613.html)
"""
import os
import mimetypes
import smtplib
import json
import argparse
from email import encoders
from email.header import Header
from email.mime.text import MIMEText
from email.mime.base import MIMEBase
from email.mime.image import MIMEImage
from email.mime.audio import MIMEAudio
from email.mime.multipart import MIMEMultipart
from email.utils import parseaddr, formataddr


def format_atachment(msg, attachments=[],text=""):
    msg.attach(MIMEText(text, 'plain', 'utf-8'))
    # 添加附件就是加上一个MIMEBase，从本地读取一个图片:
    if attachments != []:
        for item in attachments:
            if not os.path.isfile(item):
                continue
            #  Guess the content type based on the file's extension.
            (ctype, encoding) = mimetypes.guess_type(item)
            if ctype is None or encoding is not None:
                ctype = 'application/octet-stream'
            (maintype, subtype) = ctype.split('/', 1)  
            # Load  and encode attachments.
            
            """
            # Use MIMEBase class construct attachments.
            with open(item, 'rb') as fp:
                attachment = MIMEBase(_maintype=maintype, _subtype=subtype)
                attachment.set_payload(fp.read())
                encoders.encode_base64(attachment)
            """
            # Use concrete type class construct attachments.
            if maintype == 'text':
                with open(item, 'rb') as fp:
                    attachment = MIMEText(fp.read(), _subtype=subtype)
            elif maintype == 'image':
                with open(item, 'rb') as fp:
                    attachment = MIMEImage(fp.read(), _subtype=subtype)
                    #在邮件中直接显示图片
                    #msg.attach(MIMEText('<html><body><h1>Hello</h1>' + '<p><img src="cid:0"></p>' + '<p>send by <a href="http://www.python.org">Python</a>...</p>' + '</body></html>','html', 'utf-8'))
                    #attachment = MIMEText(fp.read(), 'base64', 'utf-8')
                    #attachment["Content-Type"] = 'application/octet-stream'
                    # 这里的filename可以任意写，写什么名字，邮件中显示什么名字
                    #attachment["Content-Disposition"] = 'attachment; filename=test.jpg'
                    #attachment['Content-ID'] = "<0>"
                    #attachment['X-Attachment-Id'] = '0'
                    
                    #attachment.add_header('Content-Disposition', 'attachment', filename=os.path.basename(item))
                    #attachment.add_header('Content-ID', '<0>')
                    #attachment.add_header('X-Attachment-Id', '0')                     
                    #msg.attach(attachment)                    
            elif maintype == 'audio':
                with open(item, 'rb') as fp:
                    attachment = MIMEAudio(fp.read(), _subtype=subtype)
            else:
                with open(item, 'rb') as fp:
                    attachment = MIMEBase(_maintype=maintype, _subtype=subtype)
                    attachment.set_payload(fp.read())
                    encoders.encode_base64(attachment)
            
            # Set attachment header.
            attachment.add_header('Content-Disposition', 'attachment', filename=os.path.basename(item))
            attachment.add_header('Content-ID', '<0>')
            attachment.add_header('X-Attachment-Id', '0')            
            msg.attach(attachment)            
    return msg
def _format_addr(s):
    name, addr = parseaddr(s)
    return formataddr(( \
        Header(name, 'utf-8').encode(), \
        addr.encode('utf-8') if isinstance(addr, unicode) else addr))

# password 为QQ邮箱授权码
def SendEmail(text, attachment, toAddress, toName=[""], subject="", fromName="system", fromAddress="zengxm.716@qq.com",  password="uitqoarbhzqhbjdd", smtp_server="smtp.qq.com"):
    """
    text 邮件正文
    attachment 附件路径，仅支持一个
    toAddress 收件人地址列表
    toName 收件人名列表
    subject 邮件主题
    fromAddress 发件人地址
    fromName 发件人名
    password 发件人邮箱密码
    smtp_server 发件人邮箱服务器
    """

    #创建可带附件邮件对象
    msg = MIMEMultipart()
    msg = format_atachment(msg,attachment, text)
    msg['From'] = _format_addr(u'%s <%s>' % (fromName,fromAddress))
    dest = zip(toName, toAddress)
    msg['To']=""
    for addr in dest:
        msg['To'] += _format_addr(u'%s <%s>' % (addr[0], addr[1]))
    msg['Subject'] = Header(subject, 'utf-8').encode()

    server = smtplib.SMTP_SSL(smtp_server, 465)# SMTP协议默认端口是25 SMTP SSL协议默认端口是465
    server.set_debuglevel(0)
    server.login(fromAddress, password)
    print server.sendmail(fromAddress, toAddress, msg.as_string())
    server.quit()    
    
if __name__ == '__main__': 
    parser = argparse.ArgumentParser(description="Send Email ")       
    #SendEmail("这是邮件正文",["test.txt","email-test.JPG"],["zengxuemin@szzt.com.cn","137451513@qq.com"],["simon","myself"],"subject: email test");
    parser.add_argument("-m","--message",default="", help="text message")
    parser.add_argument("-a","--attachment",default="", help="attachment")
    parser.add_argument("-s","--subject", default="system message",help="email subject")
    parser.add_argument("receiver_address", help="recevier's email address")
    parser.add_argument("-n","--receiver_name",help="recevier's name")
    args = parser.parse_args()
    if not args.receiver_name:
        n = args.receiver_address.split("@")
        if len(n) != 2:
            exit(0)
        args.receiver_name = n[0]    
    SendEmail(args.message,[args.attachment],[args.receiver_address],[args.receiver_name], args.subject);


#def format_atachment(msg):
#    msg.attach(MIMEText('send with file...', 'plain', 'utf-8'))
#
#    # 添加附件就是加上一个MIMEBase，从本地读取一个图片:
#    with open('./email-test.jpg', 'rb') as f:
#        # 设置附件的MIME和文件名，这里是png类型:
#        #mime = MIMEBase('image', 'jpg', filename='email-test.jpg')
#        ## 加上必要的头信息:
#        #mime.add_header('Content-Disposition', 'attachment', filename='email-test.jpg')
#        #mime.add_header('Content-ID', '<0>')
#        #mime.add_header('X-Attachment-Id', '0')
#        ## 把附件的内容读进来:
#        #mime.set_payload(f.read())
#        ## 用Base64编码:
#        #encoders.encode_base64(mime)
#        ## 添加到 MIMEMultipart:
#        #msg.attach(mime)
#    #在邮件中直接显示图片
#        msg.attach(MIMEText('<html><body><h1>Hello</h1>' + '<p><img src="cid:0"></p>' + '<p>send by <a href="http://www.python.org">Python</a>...</p>' + '</body></html>','html', 'utf-8'))
#        att1 = MIMEText(f.read(), 'base64', 'utf-8')
#        att1["Content-Type"] = 'application/octet-stream'
#        # 这里的filename可以任意写，写什么名字，邮件中显示什么名字
#        att1["Content-Disposition"] = 'attachment; filename="emailtest.jpg"'
#        att1['Content-ID'] = "<0>"
#        att1['X-Attachment-Id'] = '0'
#        msg.attach(att1)
#    return msg
#def _format_addr(s):
#    name, addr = parseaddr(s)
#    return formataddr(( \
#        Header(name, 'utf-8').encode(), \
#        addr.encode('utf-8') if isinstance(addr, unicode) else addr))
##from_addr = "zengxuemin@szzt.com.cn"
##password = "szzt@002197"
#from_addr = "zengxm.716@qq.com"
#password = "uitqoarbhzqhbjdd" #QQ邮箱授权码
#
#
#smtp_server = "smtp.qq.com"#"mail.szzt.com.cn"
##to_addr = "zengxm.716@qq.com"
#to_addr = "zengxuemin@szzt.com.cn"
##msg = MIMEText('hello, send by Python...', 'plain', 'utf-8')
##HTML 邮件
##msg = MIMEText('<html><body><h1>Hello</h1>' + '<p><img src="cid:0"></p>'  +'<p>send by <a href="http://www.python.org">Python</a>...</p>' +  '</body></html>', 'html', 'utf-8')
##创建可带附件邮件对象
#msg = MIMEMultipart()
#msg = format_atachment(msg)
#msg['From'] = _format_addr(u'Python爱好者 <%s>' % from_addr)
#msg['To'] = _format_addr(u'管理员 <%s>' % to_addr)
#msg['Subject'] = Header(u'来自SMTP的问候……', 'utf-8').encode()
#
#server = smtplib.SMTP_SSL(smtp_server, 465)# SMTP协议默认端口是25 SMTP SSL协议默认端口是465
#server.set_debuglevel(1)
#server.login(from_addr, password)
#server.sendmail(from_addr, [to_addr], msg.as_string())
#server.quit()